﻿using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Http;
using TouchSocket.Http.WebSockets;
using TouchSocket.Sockets;
using System.IO;

namespace XQJCDemo
{
    public class XQJCMarketDataCollection
    {
        /// <summary>
        /// 运行状态
        /// </summary>
        public bool IsRun { get; private set; } = false;
        /// <summary>
        /// 处理线程
        /// </summary>
        private Thread _thread;
        /// <summary>
        /// wss通讯
        /// </summary>
        private WebSocketClient webSocketClient = null;
        /// <summary>
        /// wss地址
        /// </summary>
        private string _url = string.Empty;
        /// <summary>
        /// 开始采集
        /// </summary>
        /// <param name="url"></param>
        public void Run(string url)
        {
            this._url = url;
            if (!this.IsRun)
            {
                this.IsRun = true;
                if (this._thread == null)
                {
                    this._thread = new Thread(work);
                    this._thread.IsBackground = true;
                    this._thread.Start();
                }
            }
        }
        /// <summary>
        /// 停止采集
        /// </summary>
        public void Stop()
        {
            this.IsRun = false;
            if (this._thread != null)
            {
                this._thread.Abort();

                this._thread = null;
            }
        }

        /// <summary>
        /// 心跳包间隔ms
        /// </summary>
        private int _heartbeatInterval { get; set; } = 1000;
        private void work()
        {
            try
            {
                while (this.IsRun)
                {
                    if (webSocketClient == null)
                    {
                        webSocketClient = new WebSocketClient();
                        webSocketClient.Setup(new TouchSocketConfig()
                            .SetRemoteIPHost(this._url)
                            .ConfigureContainer(a =>
                            {
                                a.AddConsoleLogger();
                            }).ConfigurePlugins(a =>
                            {
                                a.UseTcpReconnection();

                            })
                            );

                        MemoryStream stream = default;//中继包缓存
                        var isText = false;//标识是否为文本
                        webSocketClient.Received = async (c, e) =>
                        {
                            Console.WriteLine($"WebSocket 长度：{e.DataFrame.PayloadLength} Type：{e.DataFrame.Opcode} ddd：{e.DataFrame.PayloadData.Span.Length} fin：{e.DataFrame.FIN}");

                            Console.WriteLine($"WebSocket文本：{e.DataFrame.ToText()}");


                            if (e.DataFrame.FIN)
                            {
                                if (isText)
                                {
                                    var segment = e.DataFrame.PayloadData.AsSegment();
                                    stream.Write(segment.Array, segment.Offset, segment.Count);

                                    if (segment.Array[segment.Count - 1] == '}')
                                    {

                                        var bytes = stream.ToArray();
                                        var py = 0;
                                        if (bytes[0] != '{')
                                        {
                                            byte sss = (byte)'{';
                                            var index = Array.IndexOf(bytes, sss);
                                            py = index;
                                        }


                                        Console.WriteLine("=====================");
                                        isText = false;
                                        var message = Encoding.UTF8.GetString(bytes, py, bytes.Length - py);
                                        Console.WriteLine($"WebSocket 长度：{message.Length},文本：{message}");
                                        if (message.StartsWith("{") && message.EndsWith("}"))
                                        {
                                          
                                        }

                                        stream.Close();
                                        stream = null;
                                    }


                                }
                                else if (e.DataFrame.IsText)
                                {
                                    var message = e.DataFrame.ToText();

                                    Console.WriteLine($"WebSocket 长度：{message.Length},文本：{message}");
                                    if (message.StartsWith("{") && message.EndsWith("}"))
                                    {
                                        JObject jobject = (JObject)JsonConvert.DeserializeObject(message);
                                        if (jobject["type"].ToString() == "market")
                                        {
                                            
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //否，则说明数据太大了，分中继包了。
                                //则，初始化缓存容器
                                if (stream == null)
                                {
                                    stream = new MemoryStream();
                                }
                                //下面则是缓存逻辑

                                //如果是非net6.0即以上，即：NetFramework平台使用。原因是stream不支持span写入
                                isText = true;
                                var segment = e.DataFrame.PayloadData.AsSegment();
                                stream.Write(segment.Array, segment.Offset, segment.Count);

                                //如果是net6.0以上，直接写入span即可




                            }
                            await e.InvokeNext();
                        };


                        webSocketClient.Connect();
                    }
                    if (webSocketClient != null)
                    {
                        if (webSocketClient.Online)
                        {
                            SendXT();
                        }
                        Console.WriteLine("ws连接状态：" + webSocketClient.Online);
                    }
                    Thread.Sleep(1000);
                }
            }
            catch (ThreadAbortException ex)
            {
            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
        /// 发送心跳
        /// </summary>
        private void SendXT()
        {
            this.webSocketClient.SendAsync("5.9999j.cn").Wait();
        }
    }

    class MyJsonClass : IRequestInfo
    {
        public MyJsonClass(JsonPackageKind packageKind, Encoding encoding, ReadOnlyMemory<byte> dataMemory, ReadOnlyMemory<byte> impurityMemory)
        {
            this.PackageKind = packageKind;
            this.Encoding = encoding;
            this.DataMemory = dataMemory;
            this.ImpurityMemory = impurityMemory;
        }

        public JsonPackageKind PackageKind { get; }
        public Encoding Encoding { get; }
        public ReadOnlyMemory<byte> DataMemory { get; }
        public ReadOnlyMemory<byte> ImpurityMemory { get; }
    }

    class MyCustomJsonDataHandlingAdapter : CustomJsonDataHandlingAdapter<MyJsonClass>
    {
        public MyCustomJsonDataHandlingAdapter() : base(Encoding.UTF8)
        {
        }

        protected override MyJsonClass GetInstance(JsonPackageKind packageKind, Encoding encoding, ReadOnlyMemory<byte> dataMemory, ReadOnlyMemory<byte> impurityMemory)
        {
            return new MyJsonClass(packageKind, encoding, dataMemory, impurityMemory);
        }
    }


}
